#include "Console.h"

namespace Explorer
{
    Console::Console(const ItemProvider& provider, const Item& item)
        : Root(provider)
        , RootItem(item)
        , CurrentItem(&item)
    {
        Commands["help"] = &Console::ShowHelp;
        Commands["dir"] = &Console::Dir;
        Commands["cd"] = &Console::Cd;
    }

    void Console::ProcessInput(const TestFramework::TestString& input)
    {
        TestFramework::TestString::SizeType index = input.Find(" ");
        TestFramework::TestString inputRequest = input;

        CommandsMap::const_iterator iter = Commands.find(
            index != TestFramework::TestString::NPos ? input.SubString(input.Begin(), input.Begin() + index) : input);

        if (iter != Commands.end())
        {
            RequestParams = index != TestFramework::TestString::NPos ? 
                input.SubString(input.Begin() + index + 1, input.End() - index - 1)
                : TestFramework::TestString();

            (this->*(iter->second))();
            RequestParams.Clear();
        }
        else
        {
            std::cout << "Unexpected command '" << input << "'! Type 'help' to view help." << std::endl;
        }
    }

    void Console::ShowHelp()
    {
        std::cout << "[help] - all commands description." << std::endl <<
            "[exit] - exit to system." << std::endl <<
            "[dir] - show children of current item." << std::endl <<
            "[cd Sample] - move to child with name \"Sample\"." << std::endl;
    }

    void Console::Dir()
    {
        DirConsumer consumer;
        Root.ReportChildren(*CurrentItem, consumer);
        DirConsumer::Items& items = consumer.GetResult();
        Children.Swap(items);
        ShowChilds();
    }

    void Console::Cd()
    {
    }

    void Console::ShowChilds()
    {
        for (DirConsumer::Items::ConstIterator iter = Children.Begin(); iter != Children.End(); ++iter)
        {
            if ((*iter)->IsParentType())
            {
                std::wcout << "\t+";
            }

            std::wcout << (*iter)->GetName() << std::endl;
        }
    }
}